package finance;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.math.complex.Complex;
import org.apache.commons.math.transform.FastFourierTransformer;

public class PageDistribution {
    public TreeMap<Double, Integer> page(double[] xt) {
        Complex[] transform = new FastFourierTransformer().transform(xt);
        TreeMap<Double, Integer> map = new TreeMap<Double, Integer>();
        
        double[] amps = amplitude(xt, transform);
        
        
        for(int i = 2;  i < amps.length; i++) {
            map.put(amps[i], i);
        }
        
        return map;
    }
    
    public List<Integer> top9(double[] xt) {
        List<Integer> list = new ArrayList<Integer>();
        TreeMap<Double, Integer> map = page(xt);
        
        for(int i = 0; i < 9; i++) {
            list.add(map.pollLastEntry().getValue());
        }
        
        return list;
    }

    private double[] amplitude(double[] xt, Complex[] transform ) {
        double[] amps = new double[transform.length];
        
        for (int i = 1; i < transform.length; i++) {
           double doubleReal = calcFormula(xt, transform, i);
           int period = Math.round(xt.length/ (float) i);
           
           if(period < amps.length)
               amps[period] += Math.abs(doubleReal);
        }
        
        return amps;
    }

    private double calcFormula(double[] xt, Complex[] transform, int i) {
        Complex conjugated = transform[i].conjugate().multiply(xt[i]); 
        double phi = Math.atan(-2 * Math.PI * i);
        Complex ejpt = new Complex(Math.cos(phi), Math.sin(phi));
        conjugated = conjugated.multiply(ejpt);
        double doubleReal = 2  * conjugated.getReal();
           
        return doubleReal;
    }
}
